﻿#region Creditos

/* Autor: Edilberto Sánchez Forero	*/
/* Email: esanchezfo@gmail.com		*/
/* Licencia: LGPL			*/
/* País: Colombia, Bogotá			*/

#endregion

#region Librerias

using System.Collections.Generic;
using ESF.General.Entity;
using ESF.SSO.Core.DataAccess.BasicReferences;
using ESF.General;
using ESF.SSO.Core.Entities;
using ESF.SSO.Core.Entities.BasicReferences;
using System;
using ESF.Data;
using ESF.SSO.Core.DataAccess;

#endregion


namespace ESF.SSO.Core.BusinessLogic
{
	public static class CtrlBasicReference
	{
		#region Read

		public static bool ExistsBasicReference (BasicReference pItem)
		{
			return AdoBasicReference.ExistsBasicReference (pItem);
		}


		public static BasicReference GetParentTreeBasicReference(BasicReference pChild, BasicReferenceType pBasicReferenceType)
		{
			return GetParentTreeBasicReference (pChild, pBasicReferenceType.ID);
		}


		public static BasicReference GetParentTreeBasicReference (BasicReference pChild, int pBasicReferenceTypeID)
		{
			return AdoBasicReference.GetParentTreeBasicReference (pChild, pBasicReferenceTypeID);
		}

		public static List<BasicReference> GetChildrenTreeBasicReference(List<BasicReference> pParentBasicReferences, int? pBasicReferenteTypeID)
		{
			return AdoBasicReference.GetChildrenTreeBasicReference (pParentBasicReferences, pBasicReferenteTypeID);
		}


		public static List<BasicReference> GetChildrenBasicReferences(BasicReference pParent, int pChildrenBasicReferenceTypeID)
		{
			return AdoBasicReference.GetChildrenBasicReferences (pParent, pChildrenBasicReferenceTypeID);
		}


		public static BasicReference Get (BasicReference pBR)
		{
			return AdoBasicReference.Get (pBR);
		}
		
		
		public static LocatedBasicReference Get (LocatedBasicReference pSample)
		{
			Validate.FilledObject (true, "Referencia", pSample);
			
			return AdoBasicReference.Get (pSample);
		}


		public static List<BasicReferenceType> ListTypes()
		{
			return AdoBasicReferenceType.List ();
		}
		
		
		public static BasicReferenceType GetBasicReferenceType (BasicReferenceType pSample)
		{
			return AdoBasicReferenceType.Get (pSample);
		}


		public static List<BasicReference> List(BasicReferenceTypes pBasicReferenceType)
		{
			return List (new BasicReferenceType () { ID = (int) pBasicReferenceType });
		}


		public static List<BasicReference> ListEnabled(BasicReferenceTypes pBasicReferenceType)
		{
			return List (new BasicReference () { IsEnabled = true, BasicReferenceType = new BasicReferenceType () { ID = (int) pBasicReferenceType } });
		}


		public static List<BasicReference> List(int pBasicReferenceTypeID)
		{
			return List (new BasicReferenceType () { ID = pBasicReferenceTypeID });
		}


		public static List<BasicReference> ListEnabled(int pBasicReferenceTypeID)
		{
			return List (new BasicReference () { IsEnabled = true, BasicReferenceType = new BasicReferenceType () { ID = pBasicReferenceTypeID } });
		}


		public static List<BasicReference> List(BasicReferenceType pBasicReferenceType)
		{
			return AdoBasicReference.List (new BasicReference () { BasicReferenceType = pBasicReferenceType });
		}


		public static List<BasicReference> List(BasicReference pSample)
		{
			return AdoBasicReference.List (pSample);
		}
		
		
		public static BrowseResults<BasicReference> Browse (BasicReference pSample, PaggingInfo pPagInfo)
		{
			return AdoBasicReference.Browse (pSample, pPagInfo);
		}


		public static List<BasicReference> QueryItemsByName (string prefixText, int count, params int [] pBasicReferenceTypeIDs)
		{
			if (pBasicReferenceTypeIDs == null) { throw new ArgumentException ("Type IDs is not defined", "BasicReferenceTypeIDS"); }

			return AdoBasicReference.List (
				new ESF.General.Entity.BasicReference () { Name = prefixText, 
					filBasicReferenceTypeIDs = pBasicReferenceTypeIDs }, 
				count);
		}
		
		#endregion
		
		
		#region Write

		public static void RegisterTreeRelationsValue (List<BasicReference> pTreeItemsOrdered, string pValue)
		{
			AdoBasicReference.RegisterTreeRelationsValue (pTreeItemsOrdered, pValue);
		}


		public static void RegisterTree<BR> (BR pGrandParent, BR pCommonParent, List<BR> pChildren, int pBasicReferenceTypeID) where BR : BasicReference
		{
			List<TreeBasicReference> items;


			items = new List<TreeBasicReference> (pChildren.Count);

			foreach (BR child in pChildren)
			{
				items.Add (new TreeBasicReference () { Parent = pCommonParent, Child = child });
			}

			using (ContextSingleTransactionScope TS = new ContextSingleTransactionScope (AdoESFSSO.W.ConnectionName))
			{
				AdoBasicReference.DeleteChildrenBasicReference (pGrandParent, pCommonParent, pBasicReferenceTypeID);
			
				Register (items);			

				TS.Complete ();
			}
		}

		
		public static void Register (List<TreeBasicReference> pItems)
		{
			using (ContextSingleTransactionScope TS = new ContextSingleTransactionScope (AdoESFSSO.W.ConnectionName))
			{
				foreach (TreeBasicReference item in pItems)
				{
					RegisterByCodes (item);
				}

				TS.Complete ();
			}
		}


		public static int? RegisterByCodes (TreeBasicReference pItem)
		{
			#region Validacion

			Validate.FilledObject (true, "valor", pItem);
			Validate.FilledBasRefPart ("Hijo", pItem.Child);
			Validate.FilledBasRefPart ("Padre", pItem.Parent);

			#endregion

			return AdoBasicReference.RegisterByCodes (pItem);
		}


		public static int? RegisterByIDs (TreeBasicReference pItem)
		{
			#region Validacion

			Validate.FilledObject (true, "valor", pItem);
			Validate.FilledBasRefPart ("Hijo", pItem.Child);
			Validate.FilledBasRefPart ("Padre", pItem.Parent);

			#endregion

			return AdoBasicReference.RegisterByIDs (pItem);
		}


		public static int? UnRegisterByIDs (TreeBasicReference pItem)
		{
			#region Validacion

			Validate.FilledObject (true, "valor", pItem);
			Validate.FilledBasRefPart ("Hijo", pItem.Child);
			Validate.FilledBasRefPart ("Padre", pItem.Parent);

			#endregion

			return AdoBasicReference.UnRegisterByIDs (pItem);
		}


		public static void Delete(List<BasicReference> pList)
		{
			using (ContextSingleTransactionScope TS = new ContextSingleTransactionScope (AdoESFSSO.W.ConnectionName))
			{
				foreach (BasicReference item in pList)
				{
					AdoBasicReference.Delete (item);
				}
				
				TS.Complete ();
			}
		}
		
		
		public static int Register<BR> (BR pBasRef) where BR : BasicReference, IAuditableEntity
		{
			LocatedBasicReference locBasRef;

			#region Validacion
			
			Validate.FilledAuditableEntity ("Referencia", pBasRef);
			Validate.FilledID ("Tipo", pBasRef.BasicReferenceType);
			Validate.Filled (true, "Nombre", pBasRef.Name);
			Validate.Filled (true, "Código", pBasRef.Code);
			
			#endregion
			
			if (pBasRef is LocatedBasicReference)
			{
				locBasRef = pBasRef as LocatedBasicReference;

				locBasRef.Location = AdoLocation.AdjustValues (locBasRef.Location);

				using (ContextSingleTransactionScope TS = new ContextSingleTransactionScope (AdoESFSSO.W.ConnectionName, System.Data.IsolationLevel.ReadUncommitted))
				{
					locBasRef.ID = AdoBasicReference.Register (locBasRef);
				
					AdoLocation.RegisterLocation (locBasRef);

					TS.Complete ();
				}
			}
			else
			{
				using (ContextSingleTransactionScope TS = new ContextSingleTransactionScope (AdoESFSSO.W.ConnectionName, System.Data.IsolationLevel.ReadUncommitted))
				{
					pBasRef.ID = AdoBasicReference.Register<BR> (pBasRef);
				
					TS.Complete ();
				}
			}
			
			return pBasRef.ID.Value;
		}
		
		#endregion
	}
}
